

package com.maoshi.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.maoshi.shop.bean.app.dto.ShopHeadInfoDto;
import com.maoshi.shop.bean.dto.ShopDetailParam;
import com.maoshi.shop.bean.enums.AuditStatus;
import com.maoshi.shop.bean.enums.OfflineHandleEventStatus;
import com.maoshi.shop.bean.enums.OfflineHandleEventType;
import com.maoshi.shop.bean.enums.ShopStatus;
import com.maoshi.shop.bean.event.OpenShopInitEvent;
import com.maoshi.shop.bean.model.OfflineHandleEvent;
import com.maoshi.shop.bean.model.ShopAuditing;
import com.maoshi.shop.bean.model.ShopDetail;
import com.maoshi.shop.bean.model.ShopWallet;
import com.maoshi.shop.bean.param.OfflineHandleEventAuditParam;
import com.maoshi.shop.common.config.Constant;
import com.maoshi.shop.common.exception.MaoshiShopBindException;
import com.maoshi.shop.common.util.PageParam;
import com.maoshi.shop.dao.ProductMapper;
import com.maoshi.shop.dao.ShopDetailMapper;
import com.maoshi.shop.dao.ShopWalletMapper;
import com.maoshi.shop.service.OfflineHandleEventService;
import com.maoshi.shop.service.ShopAuditingService;
import com.maoshi.shop.service.ShopDetailService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author lgh on 2018/08/29.
 */
@Service
@AllArgsConstructor
public class ShopDetailServiceImpl extends ServiceImpl<ShopDetailMapper, ShopDetail> implements ShopDetailService {

    private final ShopDetailMapper shopDetailMapper;

    private final ShopAuditingService shopAuditingService;

    private final MapperFacade mapperFacade;

    private final ShopWalletMapper shopWalletMapper;

    private final OfflineHandleEventService offlineHandleEventService;

    private final ProductMapper productMapper;

    private final ApplicationContext applicationContext;


    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "shop_detail", key = "#shopDetail.shopId")
    public void updateShopDetail(ShopDetail shopDetail, ShopDetail dbShopDetail) {
        // 使用saveOrUpdate可以只更新部分字段
        saveOrUpdate(shopDetail);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "shop_detail", key = "#shopId")
    public void deleteShopDetailByShopId(Long shopId) {
        // 先删除数据库中的信息，再删除图片
        shopDetailMapper.deleteById(shopId);
    }

    @Override
    @Cacheable(cacheNames = "shop_detail", key = "#shopId")
    public ShopDetail getShopDetailByShopId(Long shopId) {
        return shopDetailMapper.selectById(shopId);
    }

    @Override
    @CacheEvict(cacheNames = "shop_detail", key = "#shopId")
    public void removeShopDetailCacheByShopId(Long shopId) {
    }

    @Override
    public ShopDetail getShopByMobile(String mobile) {
        return shopDetailMapper.getShopByMobile(mobile);
    }

    @Override
    public void updatePasswordByUserName(String username, String newPassword) {
        shopDetailMapper.updatePasswordByUserName(username, newPassword);
    }

    @Override
    public ShopDetail getShopDetailByUserId(String userId) {
        return shopDetailMapper.getShopDetailByUserId(userId);
    }

    /**
     * 申请开店
     *
     * @param userId
     * @param shopDetailParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyShop(String userId, ShopDetailParam shopDetailParam) {

        ShopDetail shopDetail = getShopDetailByUserId(userId);
        if (shopDetail != null && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.NOTOPEN.value())) {
            throw new MaoshiShopBindException("您已经申请开启店铺,不能重新申请");
        }
        ShopDetail dbShopnameShop = shopDetailMapper.selectOne(new LambdaQueryWrapper<ShopDetail>().eq(ShopDetail::getShopName, shopDetailParam.getShopName()).ne(ShopDetail::getUserId, userId));
        if (dbShopnameShop != null) {
            throw new MaoshiShopBindException("店铺名称已存在");
        }
        ShopDetail newShopDetail = mapperFacade.map(shopDetailParam, ShopDetail.class);

        Date now = new Date();
        // 如果是第一次申请开店
        if (shopDetail == null) {
            newShopDetail.setUserId(userId);
            newShopDetail.setCreateTime(now);
            newShopDetail.setShopOwner(userId);
            newShopDetail.setShopStatus(ShopStatus.NOTOPEN.value());
            newShopDetail.setIsDistribution(1);
        } else {
            newShopDetail.setShopId(shopDetail.getShopId());
        }


        newShopDetail.setUpdateTime(now);
        // 保存或更新
        saveOrUpdate(newShopDetail);
        //清除缓存
        removeShopDetailCacheByShopId(newShopDetail.getShopId());

        // 插入一条审核记录
        ShopAuditing auditing = shopAuditingService.getShopAuditingByUserId(userId);
        if (auditing == null) {
            auditing = new ShopAuditing();
            auditing.setShopId(newShopDetail.getShopId());
            auditing.setUserId(userId);
            auditing.setCreateTime(new Date());
        }
        auditing.setStatus(AuditStatus.WAITAUDIT.value());
        auditing.setUpdateTime(new Date());
        shopAuditingService.saveOrUpdate(auditing);

        //申请开店的同时自动申请成为分销员
        //1.先判断是不是已经成为分销员且状态为正常    或者   已经提交过成为分销员的申请且状态不是已通过
            //提交过申请:修改状态为通过
            //已经成为分销员
//        Long shopId = Constant.PLATFORM_SHOP_ID;
//
//        DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, shopId);
    }

    /**
     * 审核商家信息
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean audit(ShopAuditing shopAuditing) {
        shopAuditingService.updateById(shopAuditing);
        if (!Objects.equals(shopAuditing.getStatus(), AuditStatus.SUCCESSAUDIT.value())) {
            return true;
        }

        //修改店铺状态
        ShopDetail shopDetail = getShopDetailByShopId(shopAuditing.getShopId());
        if (shopDetail == null) {
            throw new MaoshiShopBindException("店铺信息不存在");
        }
        shopDetail.setShopStatus(ShopStatus.OPEN.value());
        updateById(shopDetail);

        // 添加店铺钱包
        ShopWallet shopWallet = new ShopWallet();
        shopWallet.setVersion(0L);
        shopWallet.setUnsettledAmount(0.0);
        shopWallet.setSettledAmount(0.0);
        shopWallet.setFreezeAmount(0.0);
        shopWallet.setTotalSettledAmount(0.0);
        shopWallet.setShopId(shopAuditing.getShopId());
        shopWallet.setUpdateTime(new Date());
        shopWalletMapper.insert(shopWallet);

        // 新店初始化事件
        applicationContext.publishEvent(new OpenShopInitEvent(shopDetail));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "shop_detail", key = "#shopDetail.shopId")
    public void offline(ShopDetail shopDetail, String offlineReason, Long sysUserId) {
        // 添加下线处理记录
        Date now = new Date();
        OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent();
        offlineHandleEvent.setHandleId(shopDetail.getShopId());
        offlineHandleEvent.setHandleType(OfflineHandleEventType.SHOP.getValue());
        offlineHandleEvent.setCreateTime(now);
        offlineHandleEvent.setOfflineReason(offlineReason);
        offlineHandleEvent.setHandlerId(sysUserId);
        offlineHandleEvent.setShopId(shopDetail.getShopId());
        offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        offlineHandleEvent.setUpdateTime(now);
        offlineHandleEventService.save(offlineHandleEvent);

        // 更新店铺状态为下线
        shopDetailMapper.updateStatus(shopDetail.getShopId(), ShopStatus.OFFLINE.value());

        // 将该店铺所有的商品下线状态
        productMapper.offlineProdByShopId(shopDetail.getShopId());

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "shop_detail", key = "#offlineHandleEventAuditParam.handleId")
    public void auditOfflineShop(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) {
        // 审核通过
        if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) {
            // 更新店铺为营业中状态
            shopDetailMapper.updateStatus(offlineHandleEventAuditParam.getHandleId(), ShopStatus.OPEN.value());
        }
        // 审核不通过
        else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) {
            shopDetailMapper.updateStatus(offlineHandleEventAuditParam.getHandleId(), ShopStatus.OFFLINE.value());
        }
        offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId);

    }

    @Override
    public List<ShopHeadInfoDto> listHotShopsHead() {
        return shopDetailMapper.listHotShopsHead();
    }

    @Override
    public Page<ShopHeadInfoDto> searchShops(PageParam<ShopHeadInfoDto> page, ShopHeadInfoDto shopHeadInfoDto) {
        return shopDetailMapper.searchShops(page,shopHeadInfoDto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "shop_detail", key = "#shopId")
    public void auditApply(Long eventId, Long shopId, String reapplyReason) {
        // 更新活动为待审核状态
        shopDetailMapper.updateStatus(shopId, ShopStatus.OFFLINE_AUDIT.value());

        // 更新事件状态
        offlineHandleEventService.updateToApply(eventId, reapplyReason);
    }

    //合并代码开始
    @Override
    public void updateOrderTypeBasket(Integer orderTypeBasket,Long shopId) {
        shopDetailMapper.updateOrderTypeBasket(orderTypeBasket,shopId);
    }

    @Override
    public List<ShopDetail> getAllShop() {
        return shopDetailMapper.getAllShop();
    }

    @Override
    public void isDelivery(Long shopId, Integer isDelivery) {
        shopDetailMapper.isDelivery(shopId,isDelivery);
    }
    //合并代码结束

}
